var gulp = require('gulp');
minifycss = require('gulp-minify-css'),
    jshint = require('gulp-jshint'),
    gutil = require('gulp-util'),
    uglify = require('gulp-uglify'),
    imagemin = require('gulp-imagemin'),
    rename = require('gulp-rename'),
    concat = require('gulp-concat'),
    cache = require('gulp-cache'),
    del = require('del'),
    rev = require('gulp-rev'),
    revCollector = require('gulp-rev-collector'),
    runSequence = require('run-sequence'),
    cache = require('gulp-cache'),
    nodemon = require('gulp-nodemon'),
    browserSync = require('browser-sync').create(),
    reload = browserSync.reload,
    replace = require('gulp-replace');

//生成到public下的build目录
var build = 'build/assets',
    viewPath = "build/views",
    revPath = "build/rev";

//处理JS文件
gulp.task('scripts', function () {
    return gulp.src("public/**/*.js")
        //.pipe(jshint('.jshintrc'))
        //.pipe(jshint.reporter('default'))
        .pipe(uglify())
        .on('error', function (err) { gutil.log(gutil.colors.red('[Error]'), err.toString()); })
        .pipe(rev())
        .pipe(gulp.dest(build))
        .pipe(rev.manifest()) //- 生成一个rev-manifest.json
        .pipe(gulp.dest(revPath + "/scripts"))   //- 将 rev-manifest.json 保存到 rev 目录内
});

//处理CSS文件
gulp.task('styles', function () {
    return gulp.src("public/**/*.css")
        .pipe(minifycss())
        .pipe(rev())
        .pipe(gulp.dest(build))
        .pipe(rev.manifest()) //- 生成一个rev-manifest.json
        .pipe(gulp.dest(revPath + "/styles")) //- 将 rev-manifest.json 保存到 rev 目录内
});

//处理图片文件
gulp.task('images', function () {
    return gulp.src("public/**/*.{png,jpg,gif,svg}")
        .pipe(cache(imagemin({ optimizationLevel: 3, progressive: true, interlaced: true })))
        .pipe(rev())
        .pipe(gulp.dest(build))
        .pipe(rev.manifest()) //- 生成一个rev-manifest.json
        .pipe(gulp.dest(revPath + "/images")) //- 将 rev-manifest.json 保存到 rev 目录内
});

//替换html里的引用路径
gulp.task('revHtml', function () {
    return gulp.src([revPath + '/**/*.json', 'views/**/*.html'])
        .pipe(revCollector()) //- 执行文件名的替换
        .pipe(gulp.dest(viewPath)); //- 替换后的文件输出的目录
});

//替换css里的引用路径
gulp.task('revCss', function () {
    return gulp.src([revPath + '/images/*.json', 'build/assets/**/*.css'])
        .pipe(revCollector({replaceReved:true })) //- 执行文件名的替换
        .pipe(gulp.dest(build)); //- 替换后的文件输出的目录
});

//替换js里的引用路径
gulp.task('revJs', function () {
    return gulp.src([revPath + '/images/*.json', 'build/assets/**/*.js'])
        .pipe(revCollector({replaceReved:true })) //- 执行文件名的替换
        .pipe(gulp.dest(build)); //- 替换后的文件输出的目录
});

//清空public/build目录
gulp.task('clean', function (cb) {
    return del(['build/**/*']);
});

//复制
gulp.task('copy', function () {
    return gulp.src("public/**/*")
        .pipe(gulp.dest(build));
});

//监听静态文件变更，实现自动刷新，使用3344端口代理express原来的3334
gulp.task('browser-sync', function () {
    browserSync.init({
        files: ["public/**/*", "views/**/*"],
        browser: "chrome",
        proxy: 'http://localhost:3334',
        port: 3344
    });
    gulp.watch('public/**/*').on('change', reload);
    gulp.watch('views/**/*').on('change', reload);
});

//监听nodejs文件变更，实现自动重启
gulp.task('nodemon', function (cb) {
    var started = false;
    return nodemon({
        script: './bin/www'
    }).on('start', function () {
        if (!started) {
            cb();
            started = true;
        }
    });
});

//切换到开发模式，设置app.js静态文件夹和视图文件夹为public和views
gulp.task('switchToDev', function () {
    return gulp.src('app.js')
        .pipe(replace("path.join(__dirname, '/build/views')", "path.join(__dirname, 'views')"))
        .pipe(replace("path.join(__dirname, '/build/assets')", "path.join(__dirname, 'public')"))
        .pipe(replace("__dirname + '/build/assets/favicon.ico'", "__dirname + '/public/favicon.ico'"))
        .pipe(gulp.dest('./'));
});

//切换到生产模式，设置app.js静态文件夹和视图文件夹为build/assets和build/views
gulp.task('switchToProd', function () {
    return gulp.src('app.js')
        .pipe(replace("path.join(__dirname, 'views')", "path.join(__dirname, '/build/views')"))
        .pipe(replace("path.join(__dirname, 'public')", "path.join(__dirname, '/build/assets')"))
        .pipe(replace("__dirname + '/public/favicon.ico'", "__dirname + '/build/assets/favicon.ico'"))
        .pipe(gulp.dest('./'));
});

//构建，此步骤只是对css js image进行压缩，以及html引入的文件进行替换，最终生成到build文件夹，app.js并未更改，不能直接发布到服务器运行，但可发布到代码库。
gulp.task('dist', function (cb) {
    runSequence('clean', ['styles', 'scripts', 'images'], ['revHtml', 'revCss', 'revJs'], 'copy', cb);
});

//构建，完成此步骤之后，代码即可发布到正式服务器，但不能提交到代码库，因为此操作会对app.js进行更改，会影响他人开发。
gulp.task('build', function (cb) {
    runSequence('clean', ['styles', 'scripts', 'images'], ['revHtml', 'revCss', 'revJs'], 'copy', 'switchToProd', cb);
});

//开发模式。用nodemon启动服务，并且用browser-sync监听public，views目录下文件的并更，实时刷新浏览器
gulp.task('dev', function () {
    runSequence('switchToDev', 'nodemon', 'browser-sync');
});

//生产模式。用nodemon启动服务，并且执行合并压缩
gulp.task('prod', function () {
    runSequence('build', 'nodemon', 'browser-sync');
})